//
//  Rss.m
//  RssReader
//
//  Created by 曙光 王 on 12-4-24.
//  Copyright (c) 2012年 Dawn. All rights reserved.
//

#import "Rss.h"
#import <CommonCrypto/CommonDigest.h>
#import "DDXML.h"
#import "Reachability.h"

static Rss *rss;
static long long dataLength;
static long long cacheLength;
static int channelIndex;
static NSMutableData *fileData;
static NSString *dataType;
@implementation Rss
@synthesize channelsPath;
@synthesize configFilePath;
@synthesize delegate;
@synthesize channels;
@synthesize channelDateFilePath;

- (id) init{
    if (self = [super init]) {
		fileData = [[NSMutableData alloc] init];
        
    }
    return self;
}
- (void) dealloc{
    [channelsPath release];
    [configFilePath release];
    [channels release];
	[fileData release];
	[channelDateFilePath release];
    [super dealloc];
}

+ (id) shareRss{
    if (!rss) {
        rss = [[Rss alloc] init];
        
        //配置文件夹路径
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *cPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Config"];
        
        //检测配置文件夹是否存在，如果不存在就创建
        if (![[NSFileManager defaultManager] fileExistsAtPath:cPath]){
            [[NSFileManager defaultManager] createDirectoryAtPath:cPath
                                      withIntermediateDirectories:YES
                                                       attributes:nil
                                                            error:NULL];
        }
        
        cPath = [cPath stringByAppendingPathComponent:@"config.plist"];
        rss.configFilePath = cPath;
        
        //频道存放位置
        NSString *chPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Channels"];
        
        //检测频道存放文件夹是否存在，如果不存在就创建
        if (![[NSFileManager defaultManager] fileExistsAtPath:chPath]){
            [[NSFileManager defaultManager] createDirectoryAtPath:chPath
                                      withIntermediateDirectories:YES
                                                       attributes:nil
                                                            error:NULL];
        }
        rss.channelsPath = chPath;
    }
    return rss;
}

-(void) cacheChannels{
    cacheLength = 0;
    channelIndex = 0;
    if ([delegate respondsToSelector:@selector(cacheWithChannelTitle:)]) {
        NSDictionary *dict = [channels objectAtIndex:channelIndex];
        [delegate cacheWithChannelTitle:[dict objectForKey:@"Title"]];
    }
    [self downloadChannel:channelIndex];
}

-(void) cacheNextChannel{
    channelIndex++;
    if (channelIndex<[channels count]) {
        if ([delegate respondsToSelector:@selector(cacheWithChannelTitle:)]) {
            NSDictionary *dict = [channels objectAtIndex:channelIndex];
            [delegate cacheWithChannelTitle:[dict objectForKey:@"Title"]];
        }
        [self downloadChannel:channelIndex];
    }
}

- (void) saveConfig{
	[rss.channels writeToFile:configFilePath atomically:YES];
}
- (void) addChannel:(NSString *)url{
	dataType = @"addchannel";
	self.channelDateFilePath = [NSString stringWithFormat:@"%@.xml",[self channelPathForKey:url]];
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
	request.delegate = self;
	request.timeOutSeconds = TIMEOUT;
	request.requestMethod = @"GET";
	[request startAsynchronous];
}
-(void) downloadChannel:(NSInteger)channelIndex{
	dataType = @"downloadchannel";
    dataLength = 0;
	[fileData setLength:0];
    cache = YES;
    NSDictionary *channel = [channels objectAtIndex:channelIndex];
	NSDate *lastDate = (NSDate *)[channel objectForKey:@"LastUpdateTime"];
	NSDate *nowDate = [NSDate date];
	long interval = [nowDate timeIntervalSinceDate:lastDate];
	
	self.channelDateFilePath = [NSString stringWithFormat:@"%@.xml",[self channelPathForKey:[channel objectForKey:@"Url"]]];
	
	Reachability *reachablity = [Reachability reachabilityForInternetConnection];
	
	if (interval>UPDATEINTERVAL&&[reachablity currentReachabilityStatus]!=kNotReachable) {
		ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString: [channel objectForKey:@"Url"]]];
		request.delegate = self;
		request.timeOutSeconds = TIMEOUT;
		request.requestMethod = @"GET";
		[request startAsynchronous];
	}else {
		
		//检测文件是否存在
		if (![[NSFileManager defaultManager] fileExistsAtPath:channelDateFilePath]) {
			//下载
			ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString: [channel objectForKey:@"Url"]]];
			request.delegate = self;
			request.timeOutSeconds = TIMEOUT;
			request.requestMethod = @"GET";
			[request startAsynchronous];
		}else {
            if ([delegate respondsToSelector:@selector(cacheWithProgress:)]) {
                [delegate cacheWithProgress:(channelIndex + 1.0)/[channels count]];
            }
            
            [self performSelector:@selector(cacheNextChannel) withObject:nil afterDelay:0.1];
        }
	}    
}

-(void) updateChannel:(NSInteger)channelIndex{
	dataType = @"updatechannel";
	dataLength = 0;
	[fileData setLength:0];
    cache = NO;
    NSDictionary *channel = [channels objectAtIndex:channelIndex];
	NSDate *lastDate = (NSDate *)[channel objectForKey:@"LastUpdateTime"];
	NSDate *nowDate = [NSDate date];
	long interval = [nowDate timeIntervalSinceDate:lastDate];
	
	self.channelDateFilePath = [NSString stringWithFormat:@"%@.xml",[self channelPathForKey:[channel objectForKey:@"Url"]]];
	
	Reachability *reachablity = [Reachability reachabilityForInternetConnection];
	
	if (interval>UPDATEINTERVAL&&[reachablity currentReachabilityStatus]!=kNotReachable) {
		ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString: [channel objectForKey:@"Url"]]];
		request.delegate = self;
		request.timeOutSeconds = TIMEOUT;
		request.requestMethod = @"GET";
		[request startAsynchronous];
	}else {
		
		//检测文件是否存在
		if (![[NSFileManager defaultManager] fileExistsAtPath:channelDateFilePath]) {
			//下载
			ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString: [channel objectForKey:@"Url"]]];
			request.delegate = self;
			request.timeOutSeconds = TIMEOUT;
			request.requestMethod = @"GET";
			[request startAsynchronous];
		}else{
			//回调
			if ([delegate respondsToSelector:@selector(updateDidFinishedWithData:withNet:)]) {
				[delegate updateDidFinishedWithData:[NSArray arrayWithContentsOfFile:[NSString stringWithFormat:@"%@.plist",[self channelPathForKey:[channel objectForKey:@"Url"]]]] withNet:NO];
			}
		}
	}
}

-(void) updateChannelNow:(NSInteger)channelIndex{
	dataType = @"updatechannelnow";
	dataLength = 0;
	[fileData setLength:0];
	 NSDictionary *channel = [channels objectAtIndex:channelIndex];
	self.channelDateFilePath = [NSString stringWithFormat:@"%@.xml",[self channelPathForKey:[channel objectForKey:@"Url"]]];
	ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString: [channel objectForKey:@"Url"]]];
	request.delegate = self;
	request.timeOutSeconds = TIMEOUT;
	request.requestMethod = @"GET";
	[request startAsynchronous];	
}



-(void) requestFailed:(ASIHTTPRequest *)request{
	if (![dataType isEqualToString:@"addchannel"]) {
		if (!cache) {
			if ([delegate respondsToSelector:@selector(updateDidFailed)]) {
				[delegate updateDidFailed];
			}
		}else {
			if ([delegate respondsToSelector:@selector(cacheWithProgress:)]) {
				[delegate cacheWithProgress:(channelIndex + 1.0)/[channels count]];
			}
			
			[self performSelector:@selector(cacheNextChannel) withObject:nil afterDelay:0.1];
		}
	}else {
		if ([delegate respondsToSelector:@selector(channelAddedFailed:)]) {
			[delegate channelAddedFailed:@"频道添加失败"];
		}
	}

}

-(void) request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data{
	dataLength+=[data length];
	[fileData appendData:data];
	if (![dataType isEqualToString:@"addchannel"]) {
		if (!cache) {
			if ([delegate respondsToSelector:@selector(updateingWithProgress:)]) {
				[delegate updateingWithProgress:(dataLength+0.0f)/request.contentLength];
				//NSLog(@"下载进度：%f",(dataLength+0.0f)/request.contentLength);
			}
		}else {
			cacheLength+=dataLength;
			if ([delegate respondsToSelector:@selector(cacheWithDataLength:)]) {
				[delegate cacheWithDataLength:cacheLength];
			}
		}
	}
}

-(void) requestFinished:(ASIHTTPRequest *)request{
	if (fileData.length==0) {
		if (![dataType isEqualToString:@"addchannel"]) {
			if (!cache) {
				if ([delegate respondsToSelector:@selector(updateDidFailed)]) {
					[delegate updateDidFailed];
				}
			}else {
				if ([delegate respondsToSelector:@selector(cacheWithProgress:)]) {
					[delegate cacheWithProgress:(channelIndex + 1.0)/[channels count]];
				}
				
				[self performSelector:@selector(cacheNextChannel) withObject:nil afterDelay:0.1];
				
			}
		}else {
			if ([delegate respondsToSelector:@selector(channelAddedFailed:)]) {
				[delegate channelAddedFailed:@"频道添加失败"];
			}
		}
		return;
	}
	
	
	[fileData writeToFile:channelDateFilePath atomically:YES];
	
	
	//解析
	NSError *error=nil;
	NSMutableArray *dataArray = [NSMutableArray array];
	DDXMLDocument *doc = [[DDXMLDocument alloc]  initWithData:[NSData dataWithContentsOfFile:channelDateFilePath] options:0 error:&error];
	if (!error) {
		//增加频道
		if ([dataType isEqualToString:@"addchannel"]) {
			NSArray *titles = [doc nodesForXPath:@"//rss//channel//title" error:&error];
			if ([titles count]==0) {
				if ([delegate respondsToSelector:@selector(channelAddedFailed:)]) {
					[delegate channelAddedFailed:@"频道添加失败"];
				}
				return;
			}
			NSString *newUrl = [NSString stringWithFormat:@"%@",request.url];
			for (int i = 0; i < [rss.channels count]; i++) {
				NSDictionary *tdict = [rss.channels objectAtIndex:i];
				if ([[tdict objectForKey:@"Url"] isEqualToString:newUrl]) {
					if ([delegate respondsToSelector:@selector(channelAddedFailed:)]) {
						[delegate channelAddedFailed:@"频道已存在"];
					}
					return;
				}
			}
			
			DDXMLElement *itemElement = (DDXMLElement *)[titles objectAtIndex:0];
			NSString *title = [itemElement stringValue];
			NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:3];
			[dict setObject:title forKey:@"Title"];
			[dict setObject:newUrl forKey:@"Url"];
			[dict setObject:@"" forKey:@"PhotoUrl"];
			[dict setObject:[NSDate dateWithTimeIntervalSince1970:0] forKey:@"LastUpdateTime"];
			
			NSMutableDictionary *colorDict = [[NSMutableDictionary alloc] initWithCapacity:3];
			[colorDict setObject:[NSNumber numberWithFloat:1.0f] forKey:@"Alpha"];
			[colorDict setObject:[NSNumber numberWithFloat:0.35294118f] forKey:@"Red"];
			[colorDict setObject:[NSNumber numberWithFloat:0.64705882f] forKey:@"Green"];
			[colorDict setObject:[NSNumber numberWithFloat:0.89411765f] forKey:@"Blue"];
			[dict setObject:colorDict forKey:@"BgColor"];
			[colorDict release];
			
			[rss.channels addObject:dict];
			NSLog(@"%@",dict);
			
			if ([delegate respondsToSelector:@selector(channelAdded:)]) {
				[delegate channelAdded:dict];
				[dict autorelease];
				return;
			}
			
		}
		if (error) {
			if ([delegate respondsToSelector:@selector(channelAddedFailed:)]) {
				[delegate channelAddedFailed:@"频道添加失败"];
			}
			return;
		}
		
		//所有的items
		NSArray *items = [doc nodesForXPath:@"//rss//channel//item" error:&error];
		if (!error) {
			for(DDXMLElement* itemElement in items) {
				NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:3];
				for (int i = 0; i<[itemElement childCount]; i++) {
					if ([[[itemElement childAtIndex:i] name] compare:@"title" options:NSCaseInsensitiveSearch]==0) {
						[dict setObject:[[[itemElement childAtIndex:i] childAtIndex:0] stringValue] forKey:@"title"];
					}else if ([[[itemElement childAtIndex:i] name] compare:@"link" options:NSCaseInsensitiveSearch]==0) {
						[dict setObject:[[[itemElement childAtIndex:i] childAtIndex:0] stringValue] forKey:@"link"];
					}else if ([[[itemElement childAtIndex:i] name] compare:@"description" options:NSCaseInsensitiveSearch]==0) {
						[dict setObject:[[[itemElement childAtIndex:i] childAtIndex:0] stringValue] forKey:@"description"];
					}else if ([[[itemElement childAtIndex:i] name] compare:@"pubdate" options:NSCaseInsensitiveSearch]==0) {
						[dict setObject:[[[itemElement childAtIndex:i] childAtIndex:0] stringValue] forKey:@"pubdate"];
					}
				}
                [dict setObject:[NSNumber numberWithInt:0] forKey:@"flag"];         //标记为未读
				[dataArray addObject:dict];
				[dict release];
			}
		}
	}else {
		if ([dataType isEqualToString:@"addchannel"]){
			if ([delegate respondsToSelector:@selector(channelAddedFailed:)]) {
				[delegate channelAddedFailed:@"频道添加失败"];
			}
		}
		return;
	}

	NSString *dataPath = [NSString stringWithFormat:@"%@.plist",[self channelPathForKey:[NSString stringWithFormat:@"%@",request.url]]];
    
    //排序
    [dataArray sortUsingComparator:(NSComparator)^(id obj1, id obj2){
        NSDictionary *dict1 = (NSDictionary *)obj1;
        NSDictionary *dict2 = (NSDictionary *)obj2;
        
        NSDate *date1 = [PublicMethods nsDateSwithchFromDateString:[dict1 objectForKey:@"pubdate"]];
        NSDate *date2 = [PublicMethods nsDateSwithchFromDateString:[dict2 objectForKey:@"pubdate"]];
        return [date2 compare:date1];
    }];
    
    //对比已经存在的文件，修改阅读状态
    if ([[NSFileManager defaultManager] fileExistsAtPath:dataPath]){
        NSArray *tdataArray = [NSArray arrayWithContentsOfFile:dataPath];
        for (int i = 0; i < [tdataArray count]&&i<[dataArray count]; i++) {
            NSDictionary *dict = [dataArray objectAtIndex:i];
            NSDictionary *tdict = [tdataArray objectAtIndex:i];
            if ([[dict objectForKey:@"title"] isEqualToString:[tdict objectForKey:@"title"]]&&
                [[dict objectForKey:@"pubdate"] isEqualToString:[tdict objectForKey:@"pubdate"]]) {
                [dict setValue:[tdict objectForKey:@"flag"] forKey:@"flag"];
            }
        }
    }
    
	[dataArray writeToFile:dataPath atomically:YES];
    
    //更新频道
    for (int i = 0; i<[channels count]; i++) {
        NSDictionary *dict = [channels objectAtIndex:i];
        NSMutableDictionary *nDict = [[NSMutableDictionary alloc] initWithDictionary:dict copyItems:YES];
        if ([[dict objectForKey:@"Url"] isEqualToString:[NSString stringWithFormat:@"%@",request.url]]) {
            [nDict setObject:[NSDate date] forKey:@"LastUpdateTime"];
            [channels replaceObjectAtIndex:i withObject:nDict];
            [nDict release];
            [channels writeToFile:configFilePath atomically:YES];
            break;
        }
    }
    
    if (!cache) {
        if ([delegate respondsToSelector:@selector(updateDidFinishedWithData:withNet:)]) {
            [delegate updateDidFinishedWithData:dataArray withNet:YES];
        }
    }else {
        if ([delegate respondsToSelector:@selector(cacheWithProgress:)]) {
            [delegate cacheWithProgress:(channelIndex + 1.0)/[channels count]];
        }
        
        [self performSelector:@selector(cacheNextChannel) withObject:nil afterDelay:0.1];

    }
}

//返回频道文件路径，以频道的url作为Key返回key的MD5加密路径
- (NSString *) channelPathForKey:(NSString *)key{
    const char *str = [key UTF8String];
    unsigned char r[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), r);
    NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                          r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]];
    
    return [channelsPath stringByAppendingPathComponent:filename];
}

@end
